package com.yycx.module.weixin.provider.service.impl;

import com.google.common.collect.Maps;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.module.weixin.provider.config.RedisProperies;
import com.yycx.module.weixin.provider.config.WxOpenProperties;
import com.yycx.module.weixin.provider.handler.RefreshRouterHandler;
import com.yycx.module.weixin.provider.util.WxOpenConfigStorageHolder;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxRuntimeException;
import me.chanjar.weixin.open.api.WxOpenConfigStorage;
import me.chanjar.weixin.open.api.impl.WxOpenInRedisConfigStorage;
import me.chanjar.weixin.open.api.impl.WxOpenMessageRouter;
import me.chanjar.weixin.open.api.impl.WxOpenServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisPool;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;

/**
 * @author <a href="https://github.com/007gzs">007</a>
 */

@Slf4j
@Service
@EnableConfigurationProperties({WxOpenProperties.class})
public class WeiXinOpenService extends WxOpenServiceImpl {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private RedisProperies redisProperies;
    @Autowired
    private WxOpenProperties wechatOpenProperties;
    @Autowired(required = false)
    protected RefreshRouterHandler refreshRouterHandler;

    private WxOpenMessageRouter wxOpenMessageRouter;
    private volatile static JedisPool pool;

    private Map<String, WxOpenConfigStorage> wxOpenConfigStorageMap;
    ;

    @PostConstruct
    public void init() {
        List<WxOpenProperties.WxOpenConfig> configs = wechatOpenProperties.getWxOpenConfigs();
        if (configs == null) {
            throw new WxRuntimeException("无微信开放平台配置，添加下相关配置，注意别配错了！");
        }
        log.info("初始化微信开放平台配置:" + configs.toString());

        wxOpenConfigStorageMap = Maps.newHashMap();
        configs.forEach(wxOpenConfig -> {
            WxOpenInRedisConfigStorage inRedisConfigStorage = new WxOpenInRedisConfigStorage(getJedisPool());
            String componentAppId = wxOpenConfig.getComponentAppId();
            inRedisConfigStorage.setComponentAppId(componentAppId);
            inRedisConfigStorage.setComponentAppSecret(wxOpenConfig.getComponentSecret());
            inRedisConfigStorage.setComponentToken(wxOpenConfig.getComponentToken());
            inRedisConfigStorage.setComponentAesKey(wxOpenConfig.getComponentAesKey());
            wxOpenConfigStorageMap.put(componentAppId, inRedisConfigStorage);
        });
        WxOpenProperties.WxOpenConfig wxOpenConfig = configs.get(0);
        String componentAppId = wxOpenConfig.getComponentAppId();
        setMultiWxOpenConfigStorages(wxOpenConfigStorageMap, componentAppId);
        wxOpenMessageRouter = new WxOpenMessageRouter(this);
        if (FlymeUtils.isNotEmpty(refreshRouterHandler)) {
            refreshRouterHandler.refreshRouter(wxOpenMessageRouter);
        }
        wxOpenMessageRouter.rule().handler((wxMpXmlMessage, map, wxMpService, wxSessionManager) -> {
            logger.info("\n接收到 {} 公众号请求消息，内容：{}", wxMpService.getWxMpConfigStorage().getAppId(), wxMpXmlMessage);
            return null;
        }).next();
    }

    public WxOpenMessageRouter getWxOpenMessageRouter() {
        return wxOpenMessageRouter;
    }

    private JedisPool getJedisPool() {
        if (pool == null) {
            synchronized (WeiXinOpenService.class) {
                if (pool == null) {
                    pool = new JedisPool(redisProperies, redisProperies.getHost(),
                            redisProperies.getPort(), redisProperies.getConnectionTimeout(),
                            redisProperies.getSoTimeout(), redisProperies.getPassword(),
                            redisProperies.getDatabase(), redisProperies.getClientName(),
                            redisProperies.isSsl(), redisProperies.getSslSocketFactory(),
                            redisProperies.getSslParameters(), redisProperies.getHostnameVerifier());
                }
            }
        }
        return pool;
    }


    private void setMultiWxOpenConfigStorages(Map<String, WxOpenConfigStorage> configStorages, String componentAppId) {
        if (configStorages.containsKey(componentAppId)) {
            WxOpenConfigStorage wxOpenConfigStorage = configStorages.get(componentAppId);
            WxOpenConfigStorageHolder.set(componentAppId);
            setWxOpenConfigStorage(wxOpenConfigStorage);
        }
    }


    @Override
    public WxOpenConfigStorage getWxOpenConfigStorage() {
        if (this.wxOpenConfigStorageMap.size() == 1) {
            // 只有一个开放平台配置，直接返回其配置即可
            return this.wxOpenConfigStorageMap.values().iterator().next();
        }
        String componentAppId = WxOpenConfigStorageHolder.get();
        return this.wxOpenConfigStorageMap.get(componentAppId);
    }

    public boolean switchover(String componentAppId) {
        if (this.wxOpenConfigStorageMap.containsKey(componentAppId)) {
            WxOpenConfigStorageHolder.set(componentAppId);
            return true;
        }
        log.error("无法找到对应【{}】的微信开放平台配置信息，请核实！", componentAppId);
        return false;
    }
}
